{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Load and minibatch MNIST data\n",
    "(c) Deniz Yuret, 2019\n",
    "* Objective: Load the [MNIST](http://yann.lecun.com/exdb/mnist) dataset, convert into Julia arrays, split into minibatches using Knet's [minibatch](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.minibatch) function and  [Data](https://github.com/denizyuret/Knet.jl/blob/master/src/data.jl) iterator type.\n",
    "* Prerequisites: [Julia arrays](https://docs.julialang.org/en/v1/manual/arrays)\n",
    "* New functions: [dir](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.dir), [minibatch, Data](http://denizyuret.github.io/Knet.jl/latest/reference/#Knet.minibatch)\n",
    "\n",
    "In the next few notebooks, we build classification models for the MNIST handwritten digit recognition dataset. MNIST has 60000 training and 10000 test examples. Each input x consists of 784 pixels representing a 28x28 image. The corresponding output indicates the identity of the digit 0..9.\n",
    "\n",
    "![](http://yann.lecun.com/exdb/lenet/gifs/asamples.gif \"MNIST\")\n",
    "\n",
    "[image source](http://yann.lecun.com/exdb/lenet)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Load packages, import symbols\n",
    "using Knet: minibatch\n",
    "using MLDatasets: MNIST\n",
    "using Images"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "28×28×60000 Array{Float32,3}\n",
      "60000-element Array{Int64,1}\n",
      "28×28×10000 Array{Float32,3}\n",
      "10000-element Array{Int64,1}\n"
     ]
    }
   ],
   "source": [
    "# This loads the MNIST handwritten digit recognition dataset:\n",
    "xtrn,ytrn = MNIST.traindata(Float32)\n",
    "xtst,ytst = MNIST.testdata(Float32)\n",
    "println.(summary.((xtrn,ytrn,xtst,ytst)));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table><tbody><tr><td style='text-align:center;vertical-align:middle; margin: 0.5em;border:1px #90999f solid;border-collapse:collapse'><img style='max-width: 100px; max-height:100px;display:inline' src=\"\"></td><td style='text-align:center;vertical-align:middle; margin: 0.5em;border:1px #90999f solid;border-collapse:collapse'><img style='max-width: 100px; max-height:100px;display:inline' src=\"\"></td><td style='text-align:center;vertical-align:middle; margin: 0.5em;border:1px #90999f solid;border-collapse:collapse'><img style='max-width: 100px; max-height:100px;display:inline' src=\"\"></td><td style='text-align:center;vertical-align:middle; margin: 0.5em;border:1px #90999f solid;border-collapse:collapse'><img style='max-width: 100px; max-height:100px;display:inline' src=\"\"></td><td style='text-align:center;vertical-align:middle; margin: 0.5em;border:1px #90999f solid;border-collapse:collapse'><img style='max-width: 100px; max-height:100px;display:inline' src=\"\"></td></tr></tbody></table><div><small>(a vector displayed as a row to save space)</small></div>"
      ],
      "text/plain": [
       "5-element Array{Base.ReinterpretArray{Gray{Float32},2,Float32,Array{Float32,2}},1}:\n",
       " [Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); … ; Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0)]\n",
       " [Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); … ; Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0)]\n",
       " [Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); … ; Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0)]\n",
       " [Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); … ; Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0)]\n",
       " [Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); … ; Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0); Gray{Float32}(0.0f0) Gray{Float32}(0.0f0) … Gray{Float32}(0.0f0) Gray{Float32}(0.0f0)]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Here is the first five images from the test set:\n",
    "[MNIST.convert2image(xtst[:,:,i]) for i=1:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[7, 2, 1, 0, 4]\n"
     ]
    }
   ],
   "source": [
    "# Here are their labels\n",
    "println(ytst[1:5]);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100-element Knet.Train20.Data{Tuple{Array{Float32,3},Array{Int64,1}}}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# `minibatch` splits the data tensors to small chunks called minibatches.\n",
    "# It returns an iterator of (x,y) pairs.\n",
    "dtrn = minibatch(xtrn,ytrn,100)\n",
    "dtst = minibatch(xtst,ytst,100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "28×28×100 Array{Float32,3}\n",
      "100-element Array{Int64,1}\n"
     ]
    }
   ],
   "source": [
    "# Each minibatch is an (x,y) pair where x is 100 (28x28) images and y are the corresponding 100 labels.\n",
    "# Here is the first minibatch in the test set:\n",
    "(x,y) = first(dtst)\n",
    "println.(summary.((x,y)));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "600"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Iterators can be used in for loops, e.g. `for (x,y) in dtrn`\n",
    "# dtrn generates 600 minibatches of 100 images (total 60000)\n",
    "# dtst generates 100 minibatches of 100 images (total 10000)\n",
    "n = 0\n",
    "for (x,y) in dtrn\n",
    "    global n += 1\n",
    "end\n",
    "n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "julia.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Julia 1.5.0",
   "language": "julia",
   "name": "julia-1.5"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.5.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
